﻿#include "FITKAbaqusAdaptorMaterialPlastic.h"
#include "InpKeyLineSpliter.h"
#include "FITKAbaqusINPReader.h"
#include "FITKAbaqusINPWriter.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaMaterial.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaMaterialPlastic.h"

namespace IO
{

    QString FITKAbaqusAdaptorMaterialPlastic::getAdaptorClass()
    {
        return "IO::FITKAbaqusAdaptorMaterialPlastic";
    }

    bool FITKAbaqusAdaptorMaterialPlastic::adaptR()
    {
        _materialData = dynamic_cast<Interface::FITKAbaMaterial*>(_dataObj);
        if (!_materialData || !_reader) return false;

        //回退一行 处理关键字信息 校验
        _reader->backLine();

        Interface::FITKAbaMaterialBehaviorEnum::FITKAbaMaterialBehaviorType materialType = 
            Interface::FITKAbaMaterialBehaviorEnum::FITKAbaMaterialBehaviorType::Plastic;
        QString line = _reader->readLine();
        if (!line.toLower().startsWith("*plastic")) return false;
        bool create = _materialData->addMaterialBehavior(materialType);
        if (!create) return false;
        auto tempPlastic = _materialData->getMaterialBehavior(materialType);
        auto plasticData = dynamic_cast<Interface::FITKAbaMaterialPlastic*>(tempPlastic);
        if (!plasticData) return false;

        QVector<double> yieldStresss;        //屈服应力
        QVector<double> PlasticStrais;       //塑性应变
        QVector<double> setTemperatures;     //温度
        QVector<double> fieldVariables;      //字段变量
        //关键字处理
        InpKeyLineSpliter s(line, _reader);
        QString type = s["hardening"];
        if (!type.isEmpty())
        {
            //暂不支持hardening关键字
            return false;
            ////处理type类型
            //if (hardening == "JOHNSON COOK")
            //{
            //    //代码暂时未完善 ，暂不支持读取type
            //    elasticData->setPlasticType(Interface::FITKAbaMaterialElasticType::JohnsonCook);
            //}
        }
        //default
        else
        {
            plasticData->setPlasticType(Interface::FITKAbaMaterialBehaviorEnum::FITKAbaMaterialPlasticType::PlasticIsoTropic);
        }

        bool readOK = false;
        //用于判断解析每行数据是否成功
        bool ok1 = false;
        bool ok2 = false;
        //解析 代码段
        while (!_reader->atEnd())
        {
            QString line = _reader->readLine();
            if (line.trimmed().isEmpty())continue;
            QStringList sList = line.split(",");

            //关键字 段落结束
            if (line.startsWith("*"))
            {
                readOK = true;
                break;
            }

            if (sList.size() > 2)
            {
                //会随着温度变化 有可能有问题 待确认
                plasticData->setUseTemperatureDependentData(true);
            }
            else if (sList.size() < 2)
            {
                //可能的异常判断
                break;
            }

            //声明 屈服应力 塑性应变 温度
            double yieldStress, PlasticStrai, setTemperature;
            for (int i = 0; i < sList.size(); ++i)
            {
                if (sList[i].trimmed().isEmpty()) continue;
                if (i == 0) yieldStress = sList[0].toDouble(&ok1);
                else if (i == 1) PlasticStrai = sList[1].toDouble(&ok2);
                //温度这有可能有问题 待确认
                else if (i == 2) setTemperature = sList[2].toDouble();
                else if (i > 2)fieldVariables.append(sList[i].toDouble());
            }
            //if (!ok1 || !ok2) return false; 暂时注释后续无用则删除
            yieldStresss.append(yieldStress);
            PlasticStrais.append(PlasticStrai);
            setTemperatures.append(setTemperature);
        }

        if (readOK || _reader->atEnd())
        {
            plasticData->setNumberOfIsoTropicDataRows(yieldStresss.size());
            for (int i = 0; i < yieldStresss.size(); ++i)
            {
                plasticData->setIsotropicYieldStess(yieldStresss[i], i);
                plasticData->setIsotropicPlasticStrain(PlasticStrais[i], i);
                plasticData->setIsotropicTemperature(setTemperatures[i], i);
            }
            return true;
        }
        else
        {
            //未正常结束

            _materialData->removeMaterialBehavior(materialType);
            return false;
        }
    }

    bool FITKAbaqusAdaptorMaterialPlastic::adaptW()
    {
        Interface::FITKAbaMaterialBehaviorEnum::FITKAbaMaterialBehaviorType materialType = 
            Interface::FITKAbaMaterialBehaviorEnum::FITKAbaMaterialBehaviorType::Plastic;
        _materialData = dynamic_cast<Interface::FITKAbaMaterial*>(_dataObj);
        if (!_materialData || !_writer) return false;
        //获得数据结构
        auto tempPlastic = _materialData->getMaterialBehavior(materialType);
        //材料为空则返回
        if (!tempPlastic) return true;
        auto plasticData = dynamic_cast<Interface::FITKAbaMaterialPlastic*>(tempPlastic);
        if (!plasticData) return false;

        QTextStream* stream = _writer->getStream();
        int isotropiCcount = plasticData->getNumberOfIsotropicDataRows();
        if (isotropiCcount < 1) return false;
        double yieldStress, PlasticStrai, setTemperature;

        // 写出关键字
        *stream << "*Plastic" << endl;

        for (int i = 0; i < isotropiCcount; ++i)
        {
            yieldStress = plasticData->getIsotropicYieldStress(i);
            PlasticStrai = plasticData->getIsotropicPlasticStrain(i);
            *stream << _writer->double2String(yieldStress, 9, 18) << ",";
            *stream << _writer->double2String(PlasticStrai, 9, 18);

            if (plasticData->getUseTemperatureDependentData())
            {
                setTemperature = plasticData->getIsotropicTemperature(i);
                *stream << "," + _writer->double2String(setTemperature, 9, 18);
            }
            *stream << endl;
        }
        return true;
    }
}
